package com.xuanxu.blogs.module.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuanxu.blogs.framework.common.exception.MissRequestParameterException;
import com.xuanxu.blogs.module.user.entity.dao.UserDao;
import com.xuanxu.blogs.module.user.entity.po.User;
import com.xuanxu.blogs.module.user.exception.UserAlreadyExistException;
import com.xuanxu.blogs.module.user.mapper.UserMapper;
import com.xuanxu.blogs.module.user.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

import static com.xuanxu.blogs.module.user.enums.UserHttpStatusEnum.USERNAME_ALREADY_EXIST;
import static com.xuanxu.blogs.module.user.enums.UserHttpStatusEnum.USER_NICKNAME_ALREADY_EXIST;

/**
 * @author XuanXu
 * @version 1.0
 * @date 2024-08-19 14:15
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
    private final UserMapper userMapper;

    @Override
    public boolean insertUser(UserDao userDao) {
        if (userDao == null) {
            return false;
        }

        // 1、判断用户是否存在
        verifyUserIsExist(userDao);

        User user = BeanUtil.copyProperties(userDao, User.class);
        int insertNumber = userMapper.insert(user);
        return insertNumber > 0;
    }

    @Override
    public boolean updateUserById(UserDao userDao) {
        if (userDao == null || userDao.getUserId() == null) {
            return false;
        }

        // 1、判断用户是否存在
        verifyUserIsExist(userDao);

        LambdaUpdateWrapper<User> userLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        userLambdaUpdateWrapper.set(StrUtil.isNotEmpty(userDao.getUserAvatar()), User::getUserAvatar, userDao.getUserAvatar());
        userLambdaUpdateWrapper.set(StrUtil.isNotEmpty(userDao.getUserNickname()), User::getUserNickname, userDao.getUserNickname());
        userLambdaUpdateWrapper.set(StrUtil.isNotEmpty(userDao.getPassword()), User::getPassword, userDao.getPassword());
        userLambdaUpdateWrapper.set(userDao.getUserStatus() != null, User::getUserStatus, userDao.getUserStatus());
        userLambdaUpdateWrapper.set(userDao.getUserType() != null, User::getUserType, userDao.getUserType());
        userLambdaUpdateWrapper.eq(User::getUserId, userDao.getUserId());
        int updateNumber = userMapper.update(new User(), userLambdaUpdateWrapper);

        return updateNumber > 0;
    }

    @Override
    public List<UserDao> selectUser(UserDao userDao) {
        if (userDao == null) {
            return null;
        }

        LambdaQueryWrapper<User> userLambdaQueryWrapper = constructionSelectionCondition(userDao);
        userLambdaQueryWrapper.orderByDesc(User::getUpdateTime);
        List<User> userList = userMapper.selectList(userLambdaQueryWrapper);
        return BeanUtil.copyToList(userList, UserDao.class);
    }

    @Override
    public boolean deleteUserById(Long userId) {
        if (userId == null) {
            return false;
        }
        int deleteNumber = userMapper.deleteById(userId);
        return deleteNumber > 0;
    }

    @Override
    public IPage<UserDao> pageSelectUser(Long currentPage, Long pageSize, UserDao userDao) {
        if (userDao == null) {
            return null;
        }

        LambdaQueryWrapper<User> userLambdaQueryWrapper = constructionSelectionCondition(userDao);

        IPage<User> userPage = userMapper.selectPage(new Page<>(currentPage, pageSize), userLambdaQueryWrapper);
        IPage<UserDao> userDaoPage = new Page<>();
        BeanUtil.copyProperties(userPage, userDaoPage);

        if (userPage != null) {
            List<UserDao> userDaoList = BeanUtil.copyToList(userPage.getRecords(), UserDao.class);
            userDaoPage.setRecords(userDaoList);
        }

        return userDaoPage;
    }

    @Override
    public UserDao selectUserByUserId(Long userId) {
        if (userId == null) {
            return null;
        }

        User user = userMapper.selectById(userId);
        return BeanUtil.copyProperties(user, UserDao.class);
    }


    /**
     * 验证用户是否存在
     * @param userDao 用户 dao 对象
     */
    private void verifyUserIsExist(UserDao userDao) {
        if (userDao == null) {
            return;
        }

        // 1、验证用户名是否存在
        verifyUsernameIsExist(userDao.getUserId(), userDao.getUsername());

        verifyUserNicknameIsExist(userDao.getUserId(), userDao.getUserNickname());
    }

    /**
     * 验证用户名是否存在
     * @param userId 用户ID
     * @param username 用户名
     */
    private void verifyUsernameIsExist(Long userId, String username) {
        if (StrUtil.isEmpty(username)) {
            throw new MissRequestParameterException();
        }

        // 查询同名用户
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getUsername, username);
        User user = userMapper.selectOne(userLambdaQueryWrapper);

        if (user == null) {
            return;
        }

        // 同一个用户就能够修改
        if (userId != null && Objects.equals(user.getUserId(), userId)) {
            return;
        }

        throw new UserAlreadyExistException(USERNAME_ALREADY_EXIST);
    }

    /**
     * 验证用户昵称是否存在
     * @param userId 用户ID
     * @param userNickname 用户昵称
     */
    private void verifyUserNicknameIsExist(Long userId, String userNickname) {
        if (StrUtil.isEmpty(userNickname)) {
            throw new MissRequestParameterException();
        }

        // 查询同名用户
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getUserNickname, userNickname);
        User user = userMapper.selectOne(userLambdaQueryWrapper);

        if (user == null) {
            return;
        }

        // 同一个用户就能够修改
        if (userId != null && Objects.equals(user.getUserId(), userId)) {
            return;
        }

        throw new UserAlreadyExistException(USER_NICKNAME_ALREADY_EXIST);
    }

    /**
     * 构造查询条件
     * @param userDAO 用户 dao 对象
     * @return 查询条件对象
     */
    private LambdaQueryWrapper<User> constructionSelectionCondition(UserDao userDAO) {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();

        if (userDAO == null) {
            return userLambdaQueryWrapper;
        }

        userLambdaQueryWrapper.like(StrUtil.isNotEmpty(userDAO.getUserNickname()), User::getUserNickname, userDAO.getUserNickname());
        userLambdaQueryWrapper.like(StrUtil.isNotEmpty(userDAO.getUsername()), User::getUsername, userDAO.getUsername());
        userLambdaQueryWrapper.eq(userDAO.getUserStatus() != null, User::getUserStatus, userDAO.getUserStatus());
        userLambdaQueryWrapper.eq(userDAO.getUserType() != null, User::getUserType, userDAO.getUserType());

        return userLambdaQueryWrapper;
    }
}
